package pl.com.britenet.myredmine.commons.dbunit;

import java.io.File;
import java.util.Date;

import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.After;
import org.junit.Before;
import org.springframework.context.ApplicationContext;

import pl.com.britenet.myredmine.commons.utils.HSQLDBServerUtil;
import pl.com.britenet.myredmine.commons.utils.HsqlDataTypeFactory;


public abstract class BaseDbUnitTestCase extends DBTestCase {
    /**
     * Spring application context;
     */
    protected ApplicationContext ctx;

    /**
     * Hibernate Session Factory.
     */
    protected static SessionFactory sessionFactory;

    /**
     * Hibernate Session.
     */
    protected Session session;

    /**
     * Hibernate transaction.
     */
    protected Transaction transaction;

    /**
     * DBUnit Base Constructor
     * 
     * @author <a href="mailto:pawel.sprysak@britenet.com.pl">Paweł Sprysak</a>
     */
	public BaseDbUnitTestCase() {
		//super();
        System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.hsqldb.jdbcDriver" );
        System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:hsqldb:mem:MYREDMINEDB" );
        System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa" );
        System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "" );
	}
  
    /**
     * Starting HSQLServer and creating Hibernate Session Factory.
     * 
     * @throws Exception
     *             In case of startup failure.
     */
    @Before
    public void setUp() throws Exception {
        sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
        session = sessionFactory.getCurrentSession();

        HSQLDBServerUtil.getInstance().startServer("MYREDMINEDB"); //potrzebne?
        super.setUp();
        getDatabaseTester().getConnection().getConfig()
                .setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqlDataTypeFactory());

        transaction = session.beginTransaction();
    }
    
    @Override
    protected IDataSet getDataSet() throws Exception {
        ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSetBuilder().build((new File(
                getDateSetFileName()))));
        dataSet.addReplacementObject("[NULL]", null);	//dodatkowo
        dataSet.addReplacementObject("[NOW]", new Date()); //dodatkowo
        dataSet.setStrictReplacement(true); //dodatkowo
        return dataSet;
    }
	
    /**
     * Shutting down HSQLServer .
     * 
     * @throws Exception
     *             In case of errors.
     */
    @After
    public void tearDown() throws Exception {

        session.flush();
        transaction.rollback();
        super.tearDown();
        HSQLDBServerUtil.getInstance().stopServer();
    }

    /** {@inheritDoc} */
    protected DatabaseOperation getSetUpOperation() throws Exception {
        return DatabaseOperation.CLEAN_INSERT;
    }

    /** {@inheritDoc} */
    protected DatabaseOperation getTearDownOperation() throws Exception {
        return DatabaseOperation.DELETE_ALL;
    }

    /**
     * Getting file name with data set.
     */
    protected abstract String getDateSetFileName();
}
